/*
 * Copyright (C) 2018 ETH Zurich, University of Bologna
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef __ARCHI_HYPER_H__
#define __ARCHI_HYPER_H__

#define REG_ACCESS    0x1
#define MEM_ACCESS    0x0

// Memory base address
#define REG_MBR0      0
// HYPER RAM 8 Mbytes / 2 = 4M address, here is 16M
#define REG_MBR1      0x01000000

#define REG_MBR_WIDTH 24

#define HYPER_EXT_ADDR_CHANNEL_OFFSET     0x00
#define HYPER_EXT_CFG_CHANNEL_OFFSET      0x04
#define HYPER_MEM_CFG0_CHANNEL_OFFSET     0x08
#define HYPER_MEM_CFG1_CHANNEL_OFFSET     0x0C
#define HYPER_MEM_CFG2_CHANNEL_OFFSET     0x10
#define HYPER_MEM_CFG3_CHANNEL_OFFSET     0x14
#define HYPER_MEM_CFG4_CHANNEL_OFFSET     0x18
#define HYPER_MEM_CFG5_CHANNEL_OFFSET     0x1C
#define HYPER_MEM_CFG6_CHANNEL_OFFSET     0x20
#define HYPER_MEM_CFG7_CHANNEL_OFFSET     0x24
#define HYPER_NB_REGS                     10

#define HYPER_EXT_ADDR_CHANNEL_CUSTOM_OFFSET     0x20
#define HYPER_EXT_CFG_CHANNEL_CUSTOM_OFFSET      0x24
#define HYPER_MEM_CFG0_CHANNEL_CUSTOM_OFFSET     0x28
#define HYPER_MEM_CFG1_CHANNEL_CUSTOM_OFFSET     0x2C
#define HYPER_MEM_CFG2_CHANNEL_CUSTOM_OFFSET     0x30
#define HYPER_MEM_CFG3_CHANNEL_CUSTOM_OFFSET     0x34
#define HYPER_MEM_CFG4_CHANNEL_CUSTOM_OFFSET     0x38
#define HYPER_MEM_CFG5_CHANNEL_CUSTOM_OFFSET     0x3C
#define HYPER_MEM_CFG6_CHANNEL_CUSTOM_OFFSET     0x40
#define HYPER_MEM_CFG7_CHANNEL_CUSTOM_OFFSET     0x44

#define HYPER_EXT_ADDR_OFFSET     (UDMA_HYPER_OFFSET(0) + HYPER_EXT_ADDR_CHANNEL_CUSTOM_OFFSET)
#define HYPER_EXT_CFG_OFFSET      (UDMA_HYPER_OFFSET(0) + HYPER_EXT_CFG_CHANNEL_CUSTOM_OFFSET)
#define HYPER_MEM_CFG0_OFFSET     (UDMA_HYPER_OFFSET(0) + HYPER_MEM_CFG0_CHANNEL_CUSTOM_OFFSET)
#define HYPER_MEM_CFG1_OFFSET     (UDMA_HYPER_OFFSET(0) + HYPER_MEM_CFG1_CHANNEL_CUSTOM_OFFSET)
#define HYPER_MEM_CFG2_OFFSET     (UDMA_HYPER_OFFSET(0) + HYPER_MEM_CFG2_CHANNEL_CUSTOM_OFFSET)
#define HYPER_MEM_CFG3_OFFSET     (UDMA_HYPER_OFFSET(0) + HYPER_MEM_CFG3_CHANNEL_CUSTOM_OFFSET)
#define HYPER_MEM_CFG4_OFFSET     (UDMA_HYPER_OFFSET(0) + HYPER_MEM_CFG4_CHANNEL_CUSTOM_OFFSET)
#define HYPER_MEM_CFG5_OFFSET     (UDMA_HYPER_OFFSET(0) + HYPER_MEM_CFG5_CHANNEL_CUSTOM_OFFSET)
#define HYPER_MEM_CFG6_OFFSET     (UDMA_HYPER_OFFSET(0) + HYPER_MEM_CFG6_CHANNEL_CUSTOM_OFFSET)
#define HYPER_MEM_CFG7_OFFSET     (UDMA_HYPER_OFFSET(0) + HYPER_MEM_CFG7_CHANNEL_CUSTOM_OFFSET)

#define HYPER_EXT_ADDR            (ARCHI_UDMA_ADDR + HYPER_EXT_ADDR_OFFSET)
#define HYPER_EXT_CFG             (ARCHI_UDMA_ADDR + HYPER_EXT_CFG_OFFSET)
#define HYPER_MEM_CFG0            (ARCHI_UDMA_ADDR + HYPER_MEM_CFG0_OFFSET)
#define HYPER_MEM_CFG1            (ARCHI_UDMA_ADDR + HYPER_MEM_CFG1_OFFSET)
#define HYPER_MEM_CFG2            (ARCHI_UDMA_ADDR + HYPER_MEM_CFG2_OFFSET)
#define HYPER_MEM_CFG3            (ARCHI_UDMA_ADDR + HYPER_MEM_CFG3_OFFSET)
#define HYPER_MEM_CFG4            (ARCHI_UDMA_ADDR + HYPER_MEM_CFG4_OFFSET)
#define HYPER_MEM_CFG5            (ARCHI_UDMA_ADDR + HYPER_MEM_CFG5_OFFSET)
#define HYPER_MEM_CFG6            (ARCHI_UDMA_ADDR + HYPER_MEM_CFG6_OFFSET)
#define HYPER_MEM_CFG7            (ARCHI_UDMA_ADDR + HYPER_MEM_CFG7_OFFSET)

#define HYPER_EXT_ADDR_MASK       0xFFFFFFFF
#define HYPER_EXT_CFG_MASK        0x0000           // Not use
#define HYPER_MEM_CFG0_MASK       0x3FFF
#define HYPER_MEM_CFG1_MASK       0xFFFFFF
#define HYPER_MEM_CFG2_MASK       0x01FF01FF
#define HYPER_MEM_CFG3_MASK       0x73F
#define HYPER_MEM_CFG4_MASK       0x3FFF
#define HYPER_MEM_CFG5_MASK       0x00FFFFFF
#define HYPER_MEM_CFG6_MASK       0x01FF01FF
#define HYPER_MEM_CFG7_MASK       0x3F

// HYPER RAM CONFIG
#define HYPER_MEM_CFG0_MBR0_OFFSET              0 // HyperRam base address, default = 0x0
#define HYPER_MEM_CFG0_LATENCY0_OFFSET          8
#define HYPER_MEM_CFG0_WRAP_SIZE0_OFFSET       12

#define HYPER_MEM_CFG1_RD_CSHI0_OFFSET          0
#define HYPER_MEM_CFG1_RD_CSS0_OFFSET           4
#define HYPER_MEM_CFG1_RD_CSH0_OFFSET           8
#define HYPER_MEM_CFG1_WR_CSHI0_OFFSET         12
#define HYPER_MEM_CFG1_WR_CSS0_OFFSET          16
#define HYPER_MEM_CFG1_WR_CSH0_OFFSET          20

#define HYPER_MEM_CFG2_RD_MAX_LENGTH0_OFFSET    0
#define HYPER_MEM_CFG2_WR_MAX_LENGTH0_OFFSET    16

#define HYPER_MEM_CFG3_ACS0_OFFSET              0
#define HYPER_MEM_CFG3_TCO0_OFFSET              1
#define HYPER_MEM_CFG3_DT0_OFFSET               2
#define HYPER_MEM_CFG3_CRT0_OFFSET              3 // HyperRAM memory access 0, for register access 1
#define HYPER_MEM_CFG3_RD_MAX_LEN_EN0_OFFSET    4
#define HYPER_MEM_CFG3_WR_MAX_LEN_EN0_OFFSET    5
#define HYPER_MEM_CFG3_RDS_DELAY_ADJ_OFFSET     8

// HYPER FLASH CONFIG
#define HYPER_MEM_CFG4_MBR1_OFFSET              0// Hyperflash base address, default = MBR0 + HYPERRAM SIZE
#define HYPER_MEM_CFG4_LATENCY1_OFFSET          8
#define HYPER_MEM_CFG4_WRAP_SIZE1_OFFSET       12

#define HYPER_MEM_CFG5_RD_CSHI1_OFFSET          0
#define HYPER_MEM_CFG5_RD_CSS1_OFFSET           4
#define HYPER_MEM_CFG5_RD_CSH1_OFFSET           8
#define HYPER_MEM_CFG5_WR_CSHI1_OFFSET         12
#define HYPER_MEM_CFG5_WR_CSS1_OFFSET          16
#define HYPER_MEM_CFG5_WR_CSH1_OFFSET          20

#define HYPER_MEM_CFG6_RD_MAX_LENGTH1_OFFSET    0
#define HYPER_MEM_CFG6_WR_MAX_LENGTH1_OFFSET    16

#define HYPER_MEM_CFG7_ACS1_OFFSET              0
#define HYPER_MEM_CFG7_TCO1_OFFSET              1
#define HYPER_MEM_CFG7_DT1_OFFSET               2
#define HYPER_MEM_CFG7_CRT1_OFFSET              3 // HyperFlash memory access 0, for register access 1
#define HYPER_MEM_CFG7_RD_MAX_LEN_EN1_OFFSET    4
#define HYPER_MEM_CFG7_WR_MAX_LEN_EN1_OFFSET    5

// BITS
#define HYPER_MEM_CFG3_MASK_GEN_B(offset)      ((~(1 << offset)) & HYPER_MEM_CFG3_MASK)
#define HYPER_MEM_CFG7_MASK_GEN_B(offset)      ((~(1 << offset)) & HYPER_MEM_CFG7_MASK)
// TWO BITS
#define HYPER_MEM_CFG0_MASK_GEN_TB(offset)     ((~(0x3 << offset)) & HYPER_MEM_CFG0_MASK)
#define HYPER_MEM_CFG4_MASK_GEN_TB(offset)     ((~(0x3 << offset)) & HYPER_MEM_CFG4_MASK)
// THREE BITS
#define HYPER_MEM_CFG3_MASK_GEN_THB(offset)    ((~(0x7 << offset)) & HYPER_MEM_CFG3_MASK)
// HALF BYTES
#define HYPER_MEM_CFG0_MASK_GEN_HB(offset)     ((~(0xF << offset)) & HYPER_MEM_CFG0_MASK)
#define HYPER_MEM_CFG1_MASK_GEN_HB(offset)     ((~(0xF << offset)) & HYPER_MEM_CFG1_MASK)
#define HYPER_MEM_CFG4_MASK_GEN_HB(offset)     ((~(0xF << offset)) & HYPER_MEM_CFG4_MASK)
#define HYPER_MEM_CFG5_MASK_GEN_HB(offset)     ((~(0xF << offset)) & HYPER_MEM_CFG5_MASK)
// BYTES
#define HYPER_MEM_CFG0_MASK_GEN_BYTE(offset)   ((~(0xFF << offset)) & HYPER_MEM_CFG0_MASK)
#define HYPER_MEM_CFG4_MASK_GEN_BYTE(offset)    ((~(0xFF << offset)) & HYPER_MEM_CFG4_MASK)
// NINE BITS
#define HYPER_MEM_CFG2_MASK_GEN_NB(offset)     ((~(0x1FF << offset)) & HYPER_MEM_CFG2_MASK)
#define HYPER_MEM_CFG6_MASK_GEN_NB(offset)     ((~(0x1FF << offset)) & HYPER_MEM_CFG6_MASK)

// MASK
#define HYPER_MEM_CFG0_MBR0_MASK_BYTE           HYPER_MEM_CFG0_MASK_GEN_BYTE(HYPER_MEM_CFG0_MBR0_OFFSET)
#define HYPER_MEM_CFG0_LATENCY0_MASK_HB         HYPER_MEM_CFG0_MASK_GEN_HB(HYPER_MEM_CFG0_LATENCY0_OFFSET)
#define HYPER_MEM_CFG0_WRAP_SIZE0_MASK_TB       HYPER_MEM_CFG0_MASK_GEN_TB(HYPER_MEM_CFG0_WRAP_SIZE0_OFFSET)
#define HYPER_MEM_CFG1_RD_CSHI0_MASK_HB         HYPER_MEM_CFG1_MASK_GEN_HB(HYPER_MEM_CFG1_RD_CSHI0_OFFSET)
#define HYPER_MEM_CFG1_RD_CSS0_MASK_HB          HYPER_MEM_CFG1_MASK_GEN_HB(HYPER_MEM_CFG1_RD_CSS0_OFFSET)
#define HYPER_MEM_CFG1_RD_CSH0_MASK_HB          HYPER_MEM_CFG1_MASK_GEN_HB(HYPER_MEM_CFG1_RD_CSH0_OFFSET)
#define HYPER_MEM_CFG1_WR_CSHI0_MASK_HB         HYPER_MEM_CFG1_MASK_GEN_HB(HYPER_MEM_CFG1_WR_CSHI0_OFFSET)
#define HYPER_MEM_CFG1_WR_CSS0_MASK_HB          HYPER_MEM_CFG1_MASK_GEN_HB(HYPER_MEM_CFG1_WR_CSS0_OFFSET)
#define HYPER_MEM_CFG1_WR_CSH0_MASK_HB          HYPER_MEM_CFG1_MASK_GEN_HB(HYPER_MEM_CFG1_WR_CSH0_OFFSET)
#define HYPER_MEM_CFG2_RD_MAX_LENGTH0_MASK_NB   HYPER_MEM_CFG2_MASK_GEN_NB(HYPER_MEM_CFG2_RD_MAX_LENGTH0_OFFSET)
#define HYPER_MEM_CFG2_WR_MAX_LENGTH0_MASK_NB   HYPER_MEM_CFG2_MASK_GEN_NB(HYPER_MEM_CFG2_WR_MAX_LENGTH0_OFFSET)
#define HYPER_MEM_CFG3_ACS0_MASK_B              HYPER_MEM_CFG3_MASK_GEN_B(HYPER_MEM_CFG3_ACS0_OFFSET)
#define HYPER_MEM_CFG3_TCO0_MASK_B              HYPER_MEM_CFG3_MASK_GEN_B(HYPER_MEM_CFG3_TCO0_OFFSET)
#define HYPER_MEM_CFG3_DT0_MASK_B               HYPER_MEM_CFG3_MASK_GEN_B(HYPER_MEM_CFG3_DT0_OFFSET)
#define HYPER_MEM_CFG3_CRT0_MASK_B              HYPER_MEM_CFG3_MASK_GEN_B(HYPER_MEM_CFG3_CRT0_OFFSET)
#define HYPER_MEM_CFG3_RD_MAX_LEN_EN0_MASK_B    HYPER_MEM_CFG3_MASK_GEN_B(HYPER_MEM_CFG3_RD_MAX_LEN_EN0_OFFSET)
#define HYPER_MEM_CFG3_WR_MAX_LEN_EN0_MASK_B    HYPER_MEM_CFG3_MASK_GEN_B(HYPER_MEM_CFG3_WR_MAX_LEN_EN0_OFFSET)
#define HYPER_MEM_CFG3_RDS_DELAY_ADJ_MASK_THB   HYPER_MEM_CFG3_MASK_GEN_THB(HYPER_MEM_CFG3_RDS_DELAY_ADJ_OFFSET)

#define HYPER_MEM_CFG4_MBR1_MASK_BYTE           HYPER_MEM_CFG4_MASK_GEN_BYTE(HYPER_MEM_CFG4_MBR1_OFFSET)
// This bit is ignored when the DEVTYPE = 1 is chosen to the HyperFlash memory.
//#define HYPER_MEM_CFG4_LATENCY1_MASK_HB         HYPER_MEM_CFG4_MASK_GEN_HB(HYPER_MEM_CFG4_LATENCY1_OFFSET)
#define HYPER_MEM_CFG4_WRAP_SIZE1_MASK_TB       HYPER_MEM_CFG4_MASK_GEN_TB(HYPER_MEM_CFG4_WRAP_SIZE1_OFFSET)
#define HYPER_MEM_CFG5_RD_CSHI1_MASK_HB         HYPER_MEM_CFG5_MASK_GEN_HB(HYPER_MEM_CFG5_RD_CSHI1_OFFSET)
#define HYPER_MEM_CFG5_RD_CSS1_MASK_HB          HYPER_MEM_CFG5_MASK_GEN_HB(HYPER_MEM_CFG5_RD_CSS1_OFFSET)
#define HYPER_MEM_CFG5_RD_CSH1_MASK_HB          HYPER_MEM_CFG5_MASK_GEN_HB(HYPER_MEM_CFG5_RD_CSH1_OFFSET)
#define HYPER_MEM_CFG5_WR_CSHI1_MASK_HB         HYPER_MEM_CFG5_MASK_GEN_HB(HYPER_MEM_CFG5_WR_CSHI1_OFFSET)
#define HYPER_MEM_CFG5_WR_CSS1_MASK_HB          HYPER_MEM_CFG5_MASK_GEN_HB(HYPER_MEM_CFG5_WR_CSS1_OFFSET)
#define HYPER_MEM_CFG5_WR_CSH1_MASK_HB          HYPER_MEM_CFG5_MASK_GEN_HB(HYPER_MEM_CFG5_WR_CSH1_OFFSET)
#define HYPER_MEM_CFG6_RD_MAX_LENGTH1_MASK_NB   HYPER_MEM_CFG6_MASK_GEN_NB(HYPER_MEM_CFG6_RD_MAX_LENGTH1_OFFSET)
#define HYPER_MEM_CFG6_WR_MAX_LENGTH1_MASK_NB   HYPER_MEM_CFG6_MASK_GEN_NB(HYPER_MEM_CFG6_WR_MAX_LENGTH1_OFFSET)
#define HYPER_MEM_CFG7_ACS1_MASK_B              HYPER_MEM_CFG7_MASK_GEN_B(HYPER_MEM_CFG7_ACS1_OFFSET)
#define HYPER_MEM_CFG7_TCO1_MASK_B              HYPER_MEM_CFG7_MASK_GEN_B(HYPER_MEM_CFG7_TCO1_OFFSET)
#define HYPER_MEM_CFG7_DT1_MASK_B               HYPER_MEM_CFG7_MASK_GEN_B(HYPER_MEM_CFG7_DT1_OFFSET)
#define HYPER_MEM_CFG7_CRT1_MASK_B              HYPER_MEM_CFG7_MASK_GEN_B(HYPER_MEM_CFG7_CRT1_OFFSET)
#define HYPER_MEM_CFG7_RD_MAX_LEN_EN1_MASK_B    HYPER_MEM_CFG7_MASK_GEN_B(HYPER_MEM_CFG7_RD_MAX_LEN_EN1_OFFSET)
#define HYPER_MEM_CFG7_WR_MAX_LEN_EN1_MASK_B    HYPER_MEM_CFG7_MASK_GEN_B(HYPER_MEM_CFG7_WR_MAX_LEN_EN1_OFFSET)


#define ARCHI_UDMA_HYPER_RX_EVT           0
#define ARCHI_UDMA_HYPER_TX_EVT           1


#endif
